home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
vol_100
/
176_01
/
xlbfun.c
< prev
next >
Wrap
Text File
|
1985-12-25
|
14KB
|
648 lines
/* xlbfun.c - xlisp basic built-in functions */
/* Copyright (c) 1985, by David Michael Betz
All Rights Reserved
Permission is granted for unrestricted non-commercial use */
#include "xlisp.h"
/* external variables */
extern NODE ***xlstack,*xlenv;
extern NODE *s_car,*s_cdr,*s_nth,*s_get,*s_svalue,*s_splist,*s_aref;
extern NODE *s_lambda,*s_macro;
extern NODE *s_comma,*s_comat;
extern NODE *s_unbound;
extern char gsprefix[];
extern int gsnumber;
/* forward declarations */
FORWARD NODE *bquote1();
FORWARD NODE *defun();
FORWARD NODE *makesymbol();
/* xeval - the built-in function 'eval' */
NODE *xeval(args)
NODE *args;
{
NODE ***oldstk,*expr,*val;
/* create a new stack frame */
oldstk = xlsave(&expr,NULL);
/* get the expression to evaluate */
expr = xlarg(&args);
xllastarg(args);
/* evaluate the expression */
val = xleval(expr);
/* restore the previous stack frame */
xlstack = oldstk;
/* return the expression evaluated */
return (val);
}
/* xapply - the built-in function 'apply' */
NODE *xapply(args)
NODE *args;
{
NODE ***oldstk,*fun,*arglist,*val;
/* create a new stack frame */
oldstk = xlsave(&fun,&arglist,NULL);
/* get the function and argument list */
fun = xlarg(&args);
arglist = xlmatch(LIST,&args);
xllastarg(args);
/* if the function is a symbol, get its value */
if (symbolp(fun))
fun = xleval(fun);
/* apply the function to the arguments */
val = xlapply(fun,arglist);
/* restore the previous stack frame */
xlstack = oldstk;
/* return the expression evaluated */
return (val);
}
/* xfuncall - the built-in function 'funcall' */
NODE *xfuncall(args)
NODE *args;
{
NODE ***oldstk,*fun,*arglist,*val;
/* create a new stack frame */
oldstk = xlsave(&fun,&arglist,NULL);
/* get the function and argument list */
fun = xlarg(&args);
arglist = args;
/* if the function is a symbol, get its value */
if (symbolp(fun))
fun = xleval(fun);
/* apply the function to the arguments */
val = xlapply(fun,arglist);
/* restore the previous stack frame */
xlstack = oldstk;
/* return the expression evaluated */
return (val);
}
/* xquote - built-in function to quote an expression */
NODE *xquote(args)
NODE *args;
{
NODE *val;
/* get the argument */
val = xlarg(&args);
xllastarg(args);
/* return the quoted expression */
return (val);
}
/* xfunction - built-in function to quote a function */
NODE *xfunction(args)
NODE *args;
{
NODE *val;
/* get the argument */
val = xlarg(&args);
xllastarg(args);
/* create a closure for lambda expressions */
if (consp(val) && car(val) == s_lambda)
val = cons(val,xlenv);
/* otherwise, get the value of a symbol */
else if (symbolp(val))
val = xlgetvalue(val);
/* otherwise, its an error */
else
xlerror("not a function",val);
/* return the function */
return (val);
}
/* xlambda - lambda function */
NODE *xlambda(args)
NODE *args;
{
NODE ***oldstk,*fargs,*closure;
/* create a new stack frame */
oldstk = xlsave(&fargs,&closure,NULL);
/* get the formal argument list */
fargs = xlmatch(LIST,&args);
/* create a new function definition */
closure = cons(fargs,args);
closure = cons(s_lambda,closure);
closure = cons(closure,xlenv);
/* restore the previous stack frame */
xlstack = oldstk;
/* return the closure */
return (closure);
}
/* xbquote - back quote function */
NODE *xbquote(args)
NODE *args;
{
NODE ***oldstk,*expr,*val;
/* create a new stack frame */
oldstk = xlsave(&expr,NULL);
/* get the expression */
expr = xlarg(&args);
xllastarg(args);
/* fill in the template */
val = bquote1(expr);
/* restore the previous stack frame */
xlstack = oldstk;
/* return the result */
return (val);
}
/* bquote1 - back quote helper function */
LOCAL NODE *bquote1(expr)
NODE *expr;
{
NODE ***oldstk,*val,*list,*last,*new;
/* handle atoms */
if (atom(expr))
val = expr;
/* handle (comma <expr>) */
else if (car(expr) == s_comma) {
if (atom(cdr(expr)))
xlfail("bad comma expression");
val = xleval(car(cdr(expr)));
}
/* handle ((comma-at <expr>) ... ) */
else if (consp(car(expr)) && car(car(expr)) == s_comat) {
oldstk = xlsave(&list,&val,NULL);
if (atom(cdr(car(expr))))
xlfail("bad comma-at expression");
list = xleval(car(cdr(car(expr))));
for (last = NIL; consp(list); list = cdr(list)) {
new = consa(car(list));
if (last)
rplacd(last,new);
else
val = new;
last = new;
}
if (last)
rplacd(last,bquote1(cdr(expr)));
else
val = bquote1(cdr(expr));
xlstack = oldstk;
}
/* handle any other list */
else {
oldstk = xlsave(&val,NULL);
val = consa(NIL);
rplaca(val,bquote1(car(expr)));
rplacd(val,bquote1(cdr(expr)));
xlstack = oldstk;
}
/* return the result */
return (val);
}
/* xset - built-in function set */
NODE *xset(args)
NODE *args;
{
NODE *sym,*val;
/* get the symbol and new value */
sym = xlmatch(SYM,&args);
val = xlarg(&args);
xllastarg(args);
/* assign the symbol the value of argument 2 and the return value */
setvalue(sym,val);
/* return the result value */
return (val);
}
/* xsetq - built-in function setq */
NODE *xsetq(args)
NODE *args;
{
NODE ***oldstk,*arg,*sym,*val;
/* create a new stack frame */
oldstk = xlsave(&arg,&sym,&val,NULL);
/* initialize */
arg = args;
/* handle each pair of arguments */
while (arg) {
sym = xlmatch(SYM,&arg);
val = xlevarg(&arg);
xlsetvalue(sym,val);
}
/* restore the previous stack frame */
xlstack = oldstk;
/* return the result value */
return (val);
}
/* xsetf - built-in function 'setf' */
NODE *xsetf(args)
NODE *args;
{
NODE ***oldstk,*arg,*place,*value;
/* create a new stack frame */
oldstk = xlsave(&arg,&place,&value,NULL);
/* initialize */
arg = args;
/* handle each pair of arguments */
while (arg) {
/* get place and value */
place = xlarg(&arg);
value = xlevarg(&arg);
/* check the place form */
if (symbolp(place))
xlsetvalue(place,value);
else if (consp(place))
placeform(place,value);
else
xlfail("bad place form");
}
/* restore the previous stack frame */
xlstack = oldstk;
/* return the value */
return (value);
}
/* placeform - handle a place form other than a symbol */
LOCAL placeform(place,value)
NODE *place,*value;
{
NODE ***oldstk,*fun,*arg1,*arg2;
int i;
/* check the function name */
if ((fun = xlmatch(SYM,&place)) == s_get) {
oldstk = xlsave(&arg1,&arg2,NULL);
arg1 = xlevmatch(SYM,&place);
arg2 = xlevmatch(SYM,&place);
xllastarg(place);
xlputprop(arg1,value,arg2);
xlstack = oldstk;
}
else if (fun == s_svalue || fun == s_splist) {
oldstk = xlsave(&arg1,NULL);
arg1 = xlevmatch(SYM,&place);
xllastarg(place);
if (fun == s_svalue)
setvalue(arg1,value);
else
setplist(arg1,value);
xlstack = oldstk;
}
else if (fun == s_car || fun == s_cdr) {
oldstk = xlsave(&arg1,NULL);
arg1 = xlevmatch(LIST,&place);
xllastarg(place);
if (consp(arg1))
if (fun == s_car)
rplaca(arg1,value);
else
rplacd(arg1,value);
xlstack = oldstk;
}
else if (fun == s_nth) {
oldstk = xlsave(&arg1,&arg2,NULL);
arg1 = xlevmatch(INT,&place);
arg2 = xlevmatch(LIST,&place);
xllastarg(place);
for (i = (int)getfixnum(arg1); i > 0 && consp(arg2); --i)
arg2 = cdr(arg2);
if (consp(arg2))
rplaca(arg2,value);
xlstack = oldstk;
}
else if (fun == s_aref) {
oldstk = xlsave(&arg1,&arg2,NULL);
arg1 = xlevmatch(VECT,